import { Direction } from '@/scripts/enum'
import { Position } from '@/scripts/util'
import { WINDOW_HEIGHT, WINDOW_WIDTH } from '@/scripts/args'

const bodyGenerator = {
  [Direction.Up]: {
    x: 0,
    y: 1
  },
  [Direction.Down]: {
    x: 0,
    y: -1
  },
  [Direction.Left]: {
    x: 1,
    y: 0
  },
  [Direction.Right]: {
    x: -1,
    y: 0
  },
}

export default function Snake ({ direction, size, x, y, length }) {
  this.direction = Direction.Stop
  this.body = []

  for (let i = 1; i <= length; i++) {
    this.body.push(new Position(+x + bodyGenerator[direction].x * i, +y + bodyGenerator[direction].y * i))
  }

  this.head = new Position(x, y)
  this.row = WINDOW_WIDTH / size
  this.col = WINDOW_HEIGHT / size
}

Snake.prototype = {
  move (eatFoodFlag) {
    const justHead = this.head.copy()
    switch (this.direction) {
      case Direction.Right: {
        if (this.head.x < this.row - 1) {
          this.head.x += 1
        } else {
          this.head.x = 0
        }
        break
      }
      case Direction.Left : {
        if (this.head.x > 0) {
          this.head.x -= 1
        } else {
          this.head.x = this.row - 1
        }
        break
      }
      case Direction.Up : {
        if (this.head.y > 0) {
          this.head.y -= 1
        } else {
          this.head.y = this.col - 1
        }
        break
      }
      case Direction.Down : {
        if (this.head.y < this.col - 1) {
          this.head.y += 1
        } else {
          this.head.y = 0
        }
        break
      }
      case Direction.Stop:
        return
    }

    const tail = this.body[this.body.length - 1].copy()

    for (let i = this.body.length - 1; i > 0; i--) {
      this.body[i].copyFrom(this.body[i - 1])
    }

    /*
      push tail to the body
     */
    if (eatFoodFlag) this.body.push(tail)

    this.body[0].copyFrom(justHead)
  },
  changeDirection (direction, force = false) {
    if (!force) {
      if (this.direction === direction) return
      if (this.direction === Direction.Up && direction === Direction.Down) return
      if (this.direction === Direction.Down && direction === Direction.Up) return
      if (this.direction === Direction.Left && direction === Direction.Right) return
      if (this.direction === Direction.Right && direction === Direction.Left) return
    }
    this.direction = direction
  },
  moveHeadTo (position) {
    this.head.copyFrom(position)
    console.log(this.head)
  },
  removeTail () {
    this.body.pop()
  },
  length() {
    return this.body.length
  }
}